﻿using System;
using System.Collections.Generic;
using System.Linq;

using Infrastructure.NetExtensions;
using TempEmployees.DAL;
using TempEmployees.BLL.EntitiesExtensions;

namespace TempEmployees.Web
{
    public partial class EmployeeDetails : ABaseUserControl
    {
        private const string EMPLOYEE_EXISTS = "EMPLOYEE_EXISTS";
        private bool EmployeeExists
        {
            get
            {
                return ViewState.Get<bool>(EMPLOYEE_EXISTS);
            }
            set
            {
                ViewState.Set<bool>(EMPLOYEE_EXISTS, value);
            }
        }

        private const string NEW_ASSIGNMENT = "NEW_ASSIGNMENT";
        public bool IsNewAssignment
        {
            get
            {
                return ViewState.Get<bool>(NEW_ASSIGNMENT);
            }
            set
            {
                ViewState.Set<bool>(NEW_ASSIGNMENT, value);
            }
        }

        private const string UPDATING_EMPLOYEE = "UPDATING_EMPLOYEE";
        private bool UpdatingEmployee
        {
            get
            {
                return ViewState.Get<bool>(UPDATING_EMPLOYEE);
            }
            set
            {
                ViewState.Set<bool>(UPDATING_EMPLOYEE, value);
            }
        }

        public bool IsReadonly { get { return DataDisplayLastName.ReadOnly; } }

        protected void Page_Load(object sender, EventArgs e)
        {
            DataDisplayID.OnTextChanged = TextBoxID_TextChanged;

            if (!this.IsPostBack && DataDisplayListFaculty.Items.Count == 0)
            {
                IsNewAssignment = false;
                UpdatingEmployee = false;

                SetDropDownLists();
            }
        }

        private void SetDropDownLists()
        {
            DataDisplayListFaculty.SetDropDownList(
                (list) => DbServices.SetDropDownFaculty(list));
            DataDisplayListFaculty.Items.RemoveAt(0);

            DataDisplayListStartSem.SetDropDownList(
                (list) => DbServices.SetDropDownSemesters(list, false));
            DataDisplayListStartSem.Items.RemoveAt(0);
        }

        protected void TextBoxID_TextChanged(object sender, EventArgs e)
        {
            Employee employee = EEmployee.GetEmployeeByID(DataDisplayID.Text);
            if (employee == null) //employee is not in the db
            {
                EmployeeExists = false;
                if (IsNewAssignment)
                {
                    EnableControls(true);
                    ClearData();
                    UpdateEmployeeButton.Visible = false;
                }
            }
            else //employee is in the db
            {
                EmployeeExists = true;
                if (IsNewAssignment)
                {
                    EnableControls(false);
                    UpdateEmployeeButton.Visible = true;
                }
                FillEmployeeDetails(employee);
            }  
        }

        private void FillEmployeeDetails(Employee employee)
        {
            DataDisplayFirstName.Text = employee.FirstName;
            DataDisplayLastName.Text = employee.LastName;
            DataDisplayBirthDate.SelectedDate = employee.BirthDate;
            DataDisplayAddress.Text = employee.Address;
            DataDisplayPhone.Text = employee.Phone;
            DataDisplayCellular.Text = employee.CellPhone;
            DataDisplayEmail.Text = employee.Email;
            //faculty & start semester
            DataDisplayListFaculty.SelectedValue = employee.FacultyID;
            DataDisplayListStartSem.SelectedValue = employee.StartSemesterID;
        }

        public bool UpdateEmployee()
        {
            Employee employee = EEmployee.GetEmployeeByID(DataDisplayID.Text);
            if (employee == null || !CheckRequiredFields() || !ValidateFields()) return false;

            employee.FirstName = FirstName;
            employee.LastName = LastName;
            employee.BirthDate = BirthDate;
            employee.Address = Address;
            employee.Phone = Phone;
            employee.CellPhone = Celuular;
            employee.Email = Email;
            employee.FacultyID = Faculty;
            employee.StartSemesterID = SemesterId;

            return EEmployee.UpdateEmployee(employee);
        }

        public void ClearData()
        {
            foreach (BaseDataDisplay control in this.Controls.OfType<BaseDataDisplay>())
            {
                if (control.ID == "DataDisplayID") continue;
                control.Reset();
            }

            //enable all the controls
            EnableControls(true);   
        }

        private Employee CreateEmployee()
        {
            if (!CheckRequiredFields() || !ValidateFields()) return null;
            Employee newEmployee = EEmployee.CreateEmployee(DataDisplayID.Text, FirstName, LastName, BirthDate,
                Address, Phone, Celuular, Email, Faculty, SemesterId);
            return newEmployee;
        }

        private bool CheckRequiredFields()
        {
            List<string> errors = new List<string>();
            foreach (BaseDataDisplay control in Controls.OfType<BaseDataDisplay>())
            {
                if (control.Required && !control.IsFilled()) errors.Add(control.DisplayName);
            }
            if (errors.Count > 0)
            {
                GUIServices.SetErrorPanel(PanelEmployeeErrors, LabelError, errors, GUIServices.MESSAGE_ERR_REQUIRED);
                return false;
            }
            else
            {
                GUIServices.SetErrorPanel(PanelEmployeeErrors, LabelError, errors, "");
                return true;
            }
        }

        private bool ValidateFields()
        {
            List<string> errors = new List<string>();
            foreach (BaseDataDisplay control in Controls.OfType<BaseDataDisplay>())
            {
                if (control.IsFilled() && !control.IsValid()) errors.Add(control.DisplayName);
            }
            if (errors.Count > 0)
            {
                GUIServices.SetErrorPanel(PanelEmployeeErrors, LabelError, errors, GUIServices.MESSAGE_ERR_VALIDATION);
                return false;
            }
            else
            {
                GUIServices.SetErrorPanel(PanelEmployeeErrors, LabelError, errors, "");
                return true;
            }
        }

        public bool SetEmployeeID(string id)
        {
            DataDisplayID.Text = id;
            TextBoxID_TextChanged(new object(), new EventArgs());
            if (!EmployeeExists) DataDisplayID.Text = String.Empty;
            return EmployeeExists;
        }

        public void ReadonlyControls(bool readOnly)
        {
            foreach (BaseDataDisplay control in Controls.OfType<BaseDataDisplay>())
            {
                if (control.ID == "DataDisplayID" && readOnly) control.ReadOnly = readOnly;
                else control.ReadOnly = readOnly;
            }
        }

        public void EnableControls(bool enable)
        {
            foreach (BaseDataDisplay control in this.Controls.OfType<BaseDataDisplay>())
            {
                control.Enabled = enable;
            }
            if (!enable)
            {
                DataDisplayID.Enabled = true;
                UpdateEmployeeButton.Enabled = true;
            }
        }

        protected void ButtonUpdateEmployee_Click(object sender, EventArgs e)
        {
            UpdatingEmployee = true;
            EnableControls(true);
            UpdateEmployeeButton.Visible = false;
            //not allowed to change employee ID
            DataDisplayID.ReadOnly = true;
        }

        public Employee NewAssignmentEmployee()
        {
            if (EmployeeExists && !UpdatingEmployee)
            {
                return EEmployee.GetEmployeeByID(DataDisplayID.Text);
            }
            else if (EmployeeExists && UpdatingEmployee)
            {
                if (!UpdateEmployee()) return null;
                else return EEmployee.GetEmployeeByID(DataDisplayID.Text);
            }
            else
            {
                return CreateEmployee();
            }
        }

        #region employee details - from controls to db type

        private string FirstName { get { return DataDisplayFirstName.Text; } }
        private string LastName { get { return DataDisplayLastName.Text; } }
        private DateTime BirthDate
        {
            get
            {
                DateTime birthDate;
                DataDisplayBirthDate.GetSelectedDate(out birthDate);
                return birthDate;
            }
        }
        private string Address { get { return DataDisplayAddress.Text; } }
        private string Phone { get { return DataDisplayPhone.Text; } }
        private string Celuular { get { return DataDisplayCellular.Text; } }
        private string Email { get { return DataDisplayEmail.Text; } }
        private int Faculty { get { return DataDisplayListFaculty.SelectedValue; } }
        private int SemesterId { get { return DataDisplayListStartSem.SelectedValue; } }

        #endregion
    }
}